using System;
using System.Collections;
using System.Text;

using System.Web;
using System.Net;
using System.IO;
using System.Security.Cryptography;

namespace EntLibEC.Biz.Finance
{
	/// <summary>
	/// Summary description for NetPayAlipayUtil.
	/// </summary>
	public class NetPayAlipayUtil
	{
		public NetPayAlipayUtil()
		{
			//
			// TODO: Add constructor logic here
			//
		}

		private Hashtable paytoHash;
		private Hashtable notifyHash;
		private string validCode = "pwmksex6u50onh3xsuvepmzlk5tw03tk";

		public void SetPayto(string _key, string _value)
		{
			if ( paytoHash == null )
				paytoHash = new Hashtable(5);

			if ( paytoHash.Contains(_key))
				paytoHash[_key] = _value;
			else
				paytoHash.Add(_key, _value);
		}
		private string GetPayto(string _key)
		{
			if ( paytoHash == null)
				return "";
			if ( paytoHash.ContainsKey(_key))
			{
				return paytoHash[_key].ToString();
			}
			else
				return "";
		}

		public void SetNotify(string _key)
		{
			if ( notifyHash == null)
				notifyHash = new Hashtable(5);

			if ( HttpContext.Current.Request.QueryString[_key] == null ) //Request.QueryString[]
				return;
			if ( notifyHash.Contains(_key))
				notifyHash[_key] = HttpContext.Current.Request.QueryString[_key].ToString();
			else
				notifyHash.Add(_key, HttpContext.Current.Request.QueryString[_key].ToString());
		}

		public string GetNotify(string _key)
		{
			if ( notifyHash == null)
				return "";
			if ( notifyHash.ContainsKey(_key))
			{
				return notifyHash[_key].ToString();
			}
			else
				return "";
		}

		public string GetAT()
		{
			//sendOff & checkOut
			if ( notifyHash == null)
				return "";

			string url = "http://notify.alipay.com/trade/notify_query.do?"
				+ "msg_id=" + GetNotify("msg_id") + "&email=taobao@giftcenter.cn&order_no=" + GetNotify("order_no");
			HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);

			// Do the request to notify and get the response
			StreamReader stIn = new StreamReader(req.GetResponse().GetResponseStream());
			string strResponse = stIn.ReadToEnd();
			stIn.Close();
			return strResponse;
		}

		public bool VerifyATN()
		{
			if ( GetNotify("ac") == "")
				return false;

			StringBuilder sbAtn = new StringBuilder(100);
			for(int i=0; i<atnParams.Length;i++)
			{
				if ( notifyHash.Contains( atnParams[i]))
				{
					sbAtn.Append(atnParams[i]).Append(GetNotify(atnParams[i]));
				}
			}
			sbAtn.Append(this.validCode);
			if ( GetNotify("ac") == getMD5(sbAtn.ToString()))
			{
				return true;
			}
			else
			{
				return false;
			}
		}
		
		private string getMD5(string s)
		{
			MD5 md5 = new MD5CryptoServiceProvider();
			byte[] t = md5.ComputeHash(Encoding.GetEncoding("gb2312").GetBytes(s) );
			StringBuilder sb = new StringBuilder(32);
			for(int i=0; i<t.Length; i++)
			{
				sb.Append( t[i].ToString("x").PadLeft(2, '0'));
			}
			return sb.ToString();
		}

		public string GetPayToUrl()
		{
			if ( paytoHash == null)
				return "";

			StringBuilder sbUrl = new StringBuilder(500);
			
			
			sbUrl.Append("https://www.alipay.com/payto:").Append(GetPayto("seller")).Append("?");

			int index = 0;
			for(int i=0;i<payToParams.Length;i++)
			{
				if ( payToParams[i] != "seller" && GetPayto(payToParams[i])!="")
				{
					if ( index != 0)
						sbUrl.Append("&");

					sbUrl.Append(payToParams[i]).Append("=").Append(HttpContext.Current.Server.UrlEncode(GetPayto(payToParams[i])));
					index++;
				}
			}

		
			StringBuilder sbAc = new StringBuilder(100);
			for(int i=0;i<payToParams.Length;i++)
			{
				if ( GetPayto(payToParams[i])!="")
					sbAc.Append(payToParams[i]).Append(GetPayto(payToParams[i]));
			}
			sbAc.Append(this.validCode);
			return sbUrl.ToString() + "&ac=" + getMD5(sbAc.ToString());
		}

		private static readonly string[] payToParams = 
			new string[] {
							 "cmd",
							 "subject",
							 "body",
							 "order_no",
							 "price",
							 "url",
							 "type",
							 "number",
							 "transport",
							 "ordinary_fee",
							 "express_fee",
							 "ems_fee",
							 "readonly",
							 "buyer_msg",
							 "seller",
							 "buyer",
							 "buyer_name",
							 "buyer_address",
							 "buyer_zipcode",
							 "buyer_tel",
							 "buyer_mobile"
						 };

		public static readonly string[] atnParams = 
			new string[] {
							 "msg_id",
							 "order_no",
							 "gross",
							 "buyer_email",
							 "buyer_name",
							 "buyer_address",
							 "buyer_zipcode",
							 "buyer_tel",
							 "buyer_mobile",
							 "action",
							 "date"
						 };

		public static readonly string[] AT = 
			new string[] {
							 "msg_id",
							 "order_no",
							 "gross",
							 "buyer_email",
							 "buyer_name",
							 "buyer_address",
							 "buyer_zipcode",
							 "buyer_tel",
							 "buyer_mobile",
							 "action",
							 "date"
						 };
	}
}
